From: Jonas Dreßler Date: Tue, 18 Feb 2020 14:05:57 +0000 (+0100) Subject: keyboard: Plug a leak of KeyboardControllers X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~772^2^2~117 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=45bc8ae292a176603ff2153d8fda8e641114d7d8;p=gnome-shell.git keyboard: Plug a leak of KeyboardControllers To make sure the GC really disposes the KeyboardController object we need to remove all references to the object, which means we have to disconnect signals the object connects to, too. This also fixes a bug where keys remain pressed forever and thus also break that key on real keyboards. It happens if the OSK gets destroyed during an OSK-key is being held so the StButton of the key is not released. That means the key remains pressed in the MetaVirtualInputDevice that we are now leaking because KeyboardController isn't garbage collected. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1015 --- diff --git a/js/ui/keyboard.js b/js/ui/keyboard.js index 868a4b3d3..15d92c592 100644 --- a/js/ui/keyboard.js +++ b/js/ui/keyboard.js @@ -1255,11 +1255,7 @@ class Keyboard extends St.BoxLayout { this._clearShowIdle(); - this._keyboardController = null; - this._suggestions = null; - this._aspectContainer = null; - this._emojiSelection = null; - this._keypad = null; + this._keyboardController.destroy(); Main.layoutManager.untrackChrome(this); Main.layoutManager.keyboardBox.remove_actor(this); @@ -1844,13 +1840,20 @@ var KeyboardController = class { this._onSourcesModified.bind(this)); this._currentSource = this._inputSourceManager.currentSource; - Main.inputMethod.connect('notify::content-purpose', - this._onContentPurposeHintsChanged.bind(this)); - Main.inputMethod.connect('notify::content-hints', - this._onContentPurposeHintsChanged.bind(this)); - Main.inputMethod.connect('input-panel-state', (o, state) => { - this.emit('panel-state', state); - }); + this._notifyContentPurposeId = Main.inputMethod.connect( + 'notify::content-purpose', this._onContentPurposeHintsChanged.bind(this)); + this._notifyContentHintsId = Main.inputMethod.connect( + 'notify::content-hints', this._onContentPurposeHintsChanged.bind(this)); + this._notifyInputPanelStateId = Main.inputMethod.connect( + 'input-panel-state', (o, state) => this.emit('panel-state', state)); + } + + destroy() { + this._inputSourceManager.disconnect(this._sourceChangedId); + this._inputSourceManager.disconnect(this._sourcesModifiedId); + Main.inputMethod.disconnect(this._notifyContentPurposeId); + Main.inputMethod.disconnect(this._notifyContentHintsId); + Main.inputMethod.disconnect(this._notifyInputPanelStateId); } _onSourcesModified() {